﻿//
// © Algobox Ltd - Benn Eichhorn
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.Feeds.Finance.MarketData;
using Algobox.Toolbox.Collections;
using Algobox.Objects.Finance.Assets.Stock;

namespace Algobox.Structure.Finance.Strategies.PriceMatrix
{
    public class PriceMatrix
    {
        #region Constructors

        public PriceMatrix(IMarketFeedAdaptor marketFeed)
        {
            _marketFeed = marketFeed;
            //_viewPrices = new ConcurrentObservableCollectionView<IStock, PriceMatrixView>();
            _marketFeed.OnSubscriptionAdded += new Action<IStock, long>(OnSubscriptionAdded);
            _marketFeed.OnSubscriptionRemoved += new Action<IStock, long>(OnSubscriptionRemoved);
        }

        #endregion
        //////////////////
        #region Member Variables

        /// <summary>
        /// Identifier for the number of subscriptions that belong to this class for a particular stock
        /// </summary>
        private const int NUMBER_OF_SUBSCRIPTIONS = 4;

        IMarketFeedAdaptor _marketFeed;
        ConcurrentObservableDictionary<IStock, PriceMatrixView> _viewPrices;

        #endregion
        //////////////////
        #region Properties

        public ConcurrentObservableDictionary<IStock, PriceMatrixView> ViewPrices { get { return _viewPrices; } set { _viewPrices = value; } }

        #endregion
        //////////////////
        #region Functions

        void OnSubscriptionAdded(IStock stock, long count)
        {
            lock (stock)
            {
                // just check if exists first no point in creating extra garbage
                if (!_viewPrices.ContainsKey(stock))
                {
                    PriceMatrixView value = new PriceMatrixView(stock);
                    if (_viewPrices.TryAdd(stock, value))
                    {
                        _marketFeed.SubscribePhase(stock, value);
                        _marketFeed.SubscribeBid(stock, value);
                        _marketFeed.SubscribeAsk(stock, value);
                        _marketFeed.SubscribeLast(stock, value);
                    }
                }
            }
        }

        void OnSubscriptionRemoved(IStock stock, long count)
        {
            lock (stock)
            {
                // if we are the only one left subscribed then unsubscribe
                if (count == NUMBER_OF_SUBSCRIPTIONS)
                {
                    PriceMatrixView value;
                    if (_viewPrices.TryRemove(stock, out value))
                    {
                        _marketFeed.UnsubscribePhase(stock, value);
                        _marketFeed.UnsubscribeBid(stock, value);
                        _marketFeed.UnsubscribeAsk(stock, value);
                        _marketFeed.UnsubscribeLast(stock, value);
                    }
                }
            }
        }

        #endregion
        //////////////////
        #region Enums



        #endregion
    }
}
